package cn.kgc.config;

import cn.kgc.service.IndustryService;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author wangyue
 * @version 1.0
 */
@Configuration
// @EnableScheduling (RabbitMQ模块中已经启用了定时任务,所以这个位置可以注释掉)
public class IndustryBloomFilterConfig {
    @Resource
    private RedissonClient redissonClient;

    @Resource
    private IndustryService industryService;

    @Bean
    public RBloomFilter<String>  industryRBloomFilter(){
        //创建行业的布隆过滤器
        RBloomFilter<String> industryBloomFilter = redissonClient.getBloomFilter("industryBloomFilter");
        //设置布隆过滤器的容量和误判率
        industryBloomFilter.tryInit(10000,0.01);
        //返回布隆过滤器
        return industryBloomFilter;
    }


    /**
     * 业务的低峰期重建布隆过滤器
     * 在每天的凌晨3点重建布隆过滤器  （全量更新）
     */
    @Scheduled(cron = "0 0 3 * * ?")
    public void rebuildIndustryBloomFilter(){
        //查询出所有一级行业的ID (一定注意不要造成OOM(内存溢出) 不要一次从表中查询出海量数据)
        List<String> topIndustryId = industryService.getTopIndustryId();
        //重新创建一个新的布隆过滤器
        RBloomFilter<String> newIndustryBloomFilter=
                  redissonClient.getBloomFilter("new_industryBloomFilter");
        //指定新的布隆过滤器的容器和误差率
        newIndustryBloomFilter.tryInit(10000,0.01);
        //将一级行业的ID添加到新的布隆过滤器中
        topIndustryId.forEach(newIndustryBloomFilter::add);
        //将新的布隆过滤器替换旧的布隆过滤器(原子切换过滤器)
        redissonClient.getKeys().rename("new_industryBloomFilter", "industryBloomFilter");
    }

}